/*
 * @Author: LVGRAPE
 * @Date: 2023-08-31 10:36:20
 * @LastEditTime: 2024-12-04 09:44:40
 * @LastEditors: LVGRAPE
 * @Description:
 * @FilePath: \zino-fc-v4\ZINO\hardware\pwr\pwr_key.c
 * 可以输入预定的版权声明、个性签名、空行等
 */
#include "zino.h"
#include "pin.h"
#include "rc.h"
#include "drv_common.h"
#include <stdbool.h>
#include "acceleration.h"

#define DBG_TAG "pwr_key"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

#define PWR_KEY_PIN GET_PIN(A,0)

#define KEY_DOWN_MASK  0X80/**按下标记*/
#define KEY_LONG_PRESS_MASK  0X40/**长按标记 */
#define KEY_TIMEOUT_MASK  0X10/**超时标志，此时返回按键值*/
#define KEY_TIEMES_MASK  0X0F/**按了多少次 */
#define KEY_VALUE(x) (0x0001<<(x))


static rt_timer_t hb_timer;
static void (*hb_key_action_callback)(uint8_t times);
static void (*hb_key_longpress_callback)(void);
static bool hb_timer_running = false;
/**
 * @brief 主要按键下次数处理函数
 *
 * @param callback void hb_call(uint8_t times)
 */
void set_hb_key_action_callback(void (*callback)(uint8_t times))
{
    LOG_D("set_hb_key_action_callback:%08X\n",callback);
    hb_key_action_callback = callback;
}
/**
 * @brief 主按键长按处理函数
 *
 * @param callback
 */
void set_hb_key_long_press_action(void (*callback)(void))
{
    hb_key_longpress_callback = callback;
}
#define KEY_COUNTS 1
void keyScanPro()
{
    const uint8_t SHORT_PRESS_TIME = 25;
    const uint8_t LONG_PRESS_TIME = 100;
    const uint8_t IS_KEY_DOWN = 0X80;/**按下了 */
    const uint8_t IS_LONG_PRESS = 0X40;/**长按了 */
    const uint8_t IS_TIME_OUT = 0X10;/**退好久没按 */
    static uint8_t pressTimesRecord[KEY_COUNTS] = { 0 };
    static uint8_t pressTime[KEY_COUNTS] = { 0 };
    static uint8_t longpressTime[KEY_COUNTS] = { 0 };
    const uint16_t channel_keyscan_map[KEY_COUNTS] = { 1 };/**A,B,C,D,E,F,G,H,I,J,K,L对就的键值*/
    uint16_t keyvalu = rt_pin_read(PWR_KEY_PIN);
    for (uint8_t i = 0; i < KEY_COUNTS; i++)
    {
        if (keyvalu == channel_keyscan_map[i])
        {
            //按下了
            if (longpressTime[i] < LONG_PRESS_TIME)
            {
                longpressTime[i]++;
                pressTime[i] = SHORT_PRESS_TIME;
                pressTimesRecord[i] |= IS_KEY_DOWN;

            }
            else
            {
                pressTimesRecord[i] |= IS_LONG_PRESS;
                pressTimesRecord[i] |= IS_TIME_OUT;
                pressTimesRecord[i] &= ~IS_KEY_DOWN; //取消标记高位
                if (hb_key_longpress_callback)
                {
                    hb_key_longpress_callback();
                }
                LOG_I("long press\n");
            }

        }
        else
        {
            //松开了
            longpressTime[i] = 0;

            if (pressTimesRecord[i] & IS_KEY_DOWN)
            {
                //高位标记过，即按下过
                pressTimesRecord[i] &= ~IS_KEY_DOWN; //取消标记高位
                if ((pressTimesRecord[i] & KEY_TIEMES_MASK) < 15)
                {
                    pressTimesRecord[i]++;
                }

            }
            if (pressTime[i] > 0)
            {
                if (pressTime[i] == 1)
                {
                    pressTimesRecord[i] |= IS_TIME_OUT;//BIT4 为检测时间到
                }
                pressTime[i]--;
            }
            if (pressTimesRecord[i] & IS_TIME_OUT)
            {

                if (pressTimesRecord[i] & IS_LONG_PRESS)
                {
                    // rt_kprintf("Long press:%d \n", i);
                    pressTimesRecord[i] &= ~IS_LONG_PRESS;
                    if (hb_key_longpress_callback)
                    {
                        hb_key_longpress_callback();
                    }
                }
                else if (pressTimesRecord[i] & KEY_TIEMES_MASK)
                {
                    // uint8_t ptc = pressTimesRecord[i] & KEY_TIEMES_MASK;

                    // rc_keyActionHandle(ptc);
                    // acc_6face_calibration_key_handle(ptc);
                    // if (hb_key_action_callback)
                    // {
                    //     hb_key_action_callback(ptc);
                    // }
                    // LOG_D("hb_key_action_callback:%08X %d\n",ptc);
                }
                LOG_I("Press:%d - %d\n", i, pressTimesRecord[i] & KEY_TIEMES_MASK);;
                pressTimesRecord[i] = 0;
                hb_timer_running = FALSE;
                rt_timer_stop(hb_timer);
            }
        }
    }
}

void hb_trace_isr(void* args)
{
    // rt_kprintf("hb_timer->init_tick:%d \n", hb_timer->init_tick);
    if(!hb_timer_running)
    {
        hb_timer_running = TRUE;
        rt_timer_start(hb_timer);
    }
}

void hb_longpress_action()
{
    LOG_I("hb_longpress_action... \r\n");
    LOG_I("power shutting down... \r\n");
    zino_pwr_ctrl(PWR_CTRL_SHUTDOWN);
}

int home_botton_init()
{
    hb_timer = rt_timer_create("hb trace", keyScanPro, RT_NULL, 20, RT_TIMER_FLAG_PERIODIC);
    if (hb_timer == RT_NULL)
    {
        rt_kprintf("error in creat hb timer.\n");
        rt_kprintf("home_botton_init failure.\n");
        return -RT_ERROR;
    }
    rt_pin_mode(PWR_KEY_PIN, PIN_MODE_INPUT);
    rt_pin_attach_irq(PWR_KEY_PIN, PIN_IRQ_MODE_RISING, hb_trace_isr, RT_NULL);
    rt_pin_irq_enable(PWR_KEY_PIN, PIN_IRQ_ENABLE);
    LOG_I("home_botton_init... \r\n");
    // rt_timer_start(hb_timer);
    set_hb_key_long_press_action(hb_longpress_action);
    return RT_EOK;
}



ZINO_BOARD_EXPORT(home_botton_init);
